package csu.web.credit_bank.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import csu.web.credit_bank.mapper.AuditorsMapper;
import csu.web.credit_bank.mapper.UsersMapper;
import csu.web.credit_bank.pojo.*;
import csu.web.credit_bank.pojo.vo.CreditCertificationVo;
import csu.web.credit_bank.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import csu.web.credit_bank.utils.Result;
import csu.web.credit_bank.utils.UUIDManager;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class AuditorsServiceImpl extends ServiceImpl<AuditorsMapper, Auditor> implements AuditorsService {

    @Autowired
    private UUIDManager uuidManager;
    @Autowired
    private UsersMapper usersMapper;
    @Autowired
    private CreditCertificationsService creditCertificationsService; // 注入 CreditCertificationsService
    @Autowired
    private CreditRecordsService creditRecordsService;             // 注入 CreditRecordsService
    @Autowired
    private CreditSummaryService creditSummaryService;             // 注入 CreditSummaryService
    @Autowired
    private CoursesService coursesService; // 注入 CoursesService 以便查询课程详情

    private static final String COURSE_CERT_PREFIX = "COURSE_CERT:"; // 定义课程认证描述前缀

    @Override
    public Auditor createAuditor(Auditor auditor) {
        this.save(auditor);
        return auditor;
    }

    @Override
    public Auditor getAuditorById(String userId) {
        return this.getById(userId);
    }

    @Override
    public Auditor updateAuditor(Auditor auditor) {
        this.updateById(auditor);
        return this.getById(auditor.getUserId());
    }

    @Override
    public boolean deleteAuditor(String userId) {
        return this.removeById(userId);
    }


    /**
     * 获取待审核的学分认证申请列表
     * 查询 audit_status 为 0 (审核中) 的认证申请，并关联查询申请人用户名
     * @param page 页码
     * @param size 每页数量
     * @return 包含待审核学分认证申请的分页结果 (包含申请人用户名)
     */
    @Override
    public Result<IPage<CreditCertificationVo>> getPendingCertifications(int page, int size) { // 此处修改：返回类型
        QueryWrapper<CreditCertification> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("audit_status", 0); // 0代表审核中

        // 排除课程认证申请，因为它们有单独的列表
        queryWrapper.notLike("description", COURSE_CERT_PREFIX + "%");

        // 使用 creditCertificationsService 进行分页查询原始的 CreditCertification
        IPage<CreditCertification> pendingCertsPage = creditCertificationsService.page(new Page<>(page, size), queryWrapper);

        // 将 CreditCertification 转换为 CreditCertificationVo，并填充 applicantUsername
        List<CreditCertificationVo> voList = pendingCertsPage.getRecords().stream().map(cert -> {
            CreditCertificationVo vo = new CreditCertificationVo();
            BeanUtils.copyProperties(cert, vo); // 复制基本属性

            // 查询申请人用户名

            User applicantUser = usersMapper.selectById(cert.getApplicantId());
            if (applicantUser != null) {
                vo.setApplicantUsername(applicantUser.getUsername());
            } else {
                vo.setApplicantUsername("未知用户"); // 或者根据需求处理
            }
            return vo;
        }).collect(Collectors.toList());

        // 创建新的 IPage<CreditCertificationVo>
        IPage<CreditCertificationVo> resultPage = new Page<>(pendingCertsPage.getCurrent(), pendingCertsPage.getSize(), pendingCertsPage.getTotal());
        resultPage.setRecords(voList);

        return Result.success(resultPage);
    }
    /**
     * 新增：获取待审核的**课程**学分认证申请列表
     * 查询 audit_status 为 0 (审核中) 且 description 以 COURSE_CERT: 开头的认证申请。
     * @param page 页码
     * @param size 每页数量
     * @return 包含待审核课程学分认证申请的分页结果 (包含申请人用户名、课程名称、课程学分)
     */
    @Override
    public Result<IPage<CreditCertificationVo>> getPendingCourseCertifications(int page, int size) {
        QueryWrapper<CreditCertification> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("audit_status", 0); // 0代表审核中
        queryWrapper.like("description", COURSE_CERT_PREFIX + "%"); // 筛选课程认证

        IPage<CreditCertification> pendingCertsPage = creditCertificationsService.page(new Page<>(page, size), queryWrapper);

        List<CreditCertificationVo> voList = pendingCertsPage.getRecords().stream().map(cert -> {
            CreditCertificationVo vo = new CreditCertificationVo();
            BeanUtils.copyProperties(cert, vo); // 复制基本属性

            // 解析 description 字段以获取课程信息
            String description = cert.getDescription();
            if (description != null && description.startsWith(COURSE_CERT_PREFIX)) {
                String[] parts = description.substring(COURSE_CERT_PREFIX.length()).split(":", 4); // 分割，限制4部分
                if (parts.length >= 3) { // 至少包含 courseId, courseCredit, courseName
                    vo.setCourseName(parts[2]); // 课程名称
                    try {
                        vo.setCourseCredit(Integer.parseInt(parts[1])); // 课程学分
                    } catch (NumberFormatException e) {
                        vo.setCourseCredit(0); // 解析失败设置为0
                    }
                    // 原始描述（如果有的话）
                    if (parts.length == 4 && StringUtils.hasText(parts[3])) {
                        vo.setDescription(parts[3]); // 将原始描述设置回 description 字段
                    } else {
                        vo.setDescription(vo.getDescription().replace(encodedCourseInfo(parts), "").trim()); // 移除编码部分
                    }
                }
            }

            // 查询申请人用户名
            User applicantUser = usersMapper.selectById(cert.getApplicantId());
            if (applicantUser != null) {
                vo.setApplicantUsername(applicantUser.getUsername());
            } else {
                vo.setApplicantUsername("未知用户");
            }
            return vo;
        }).collect(Collectors.toList());

        IPage<CreditCertificationVo> resultPage = new Page<>(pendingCertsPage.getCurrent(), pendingCertsPage.getSize(), pendingCertsPage.getTotal());
        resultPage.setRecords(voList);

        return Result.success(resultPage);
    }

    // 辅助方法：用于从编码描述中提取编码部分的字符串，方便在设置原始描述时去除
    private String encodedCourseInfo(String[] parts) {
        if (parts.length >= 3) {
            return String.format("%s%s:%s:%s", COURSE_CERT_PREFIX, parts[0], parts[1], parts[2]);
        }
        return "";
    }


    /**
     * 审核学分认证申请
     * 使用 @Transactional 注解确保数据库操作的原子性，即要么全部成功，要么全部回滚。
     * @param certificationId 认证申请ID
     * @param auditStatus 审核状态 (1: 通过, 2: 拒绝)
     * @param auditorId 审核员ID
     * @param credits 授予的学分数量 (仅当通过时有效)
     * @param applicantUserId 申请人（学生）的用户ID
     * @return 审核结果
     */
    @Override
    @Transactional
    public Result auditCertification(String certificationId, int auditStatus, String auditorId, Integer credits, String applicantUserId) {
        // 1. 获取学分认证申请
        CreditCertification certification = creditCertificationsService.getById(certificationId);
        if (certification == null) {
            return Result.failure("认证申请不存在");
        }

        // 2. 检查申请是否已经审核过，避免重复操作
        if (certification.getAuditStatus() != 0) { // 0代表审核中
            return Result.failure("该申请已审核，请勿重复操作");
        }

        // 3. 更新认证申请状态
        certification.setAuditStatus(auditStatus); // 设置新的审核状态
        certification.setAuditorId(auditorId);     // 设置审核员ID
        certification.setAuditTime(new Date());    // 设置审核时间为当前时间
        creditCertificationsService.updateById(certification); // 更新学分认证记录

        // 4. 根据审核状态进行后续操作
        if (auditStatus == 1) { // 审核通过
            Integer finalCredits = credits; // 默认使用传入的credits
            String method = "其他认证";
            String courseName = null;

            String description = certification.getDescription();
            // 检查是否为课程认证，并尝试从 description 中解析课程信息
            if (description != null && description.startsWith(COURSE_CERT_PREFIX)) {
                String[] parts = description.substring(COURSE_CERT_PREFIX.length()).split(":", 4);
                if (parts.length >= 3) { // 至少包含 courseId, courseCredit, courseName
                    try {
                        // 使用解析出来的课程学分，而非审核员传入的学分
                        finalCredits = Integer.parseInt(parts[1]);
                        method = "课程学习";
                        courseName = parts[2]; // 课程名称
                    } catch (NumberFormatException e) {
                        // 如果解析失败，则仍使用传入的credits，并记录为其他认证
                        System.err.println("课程认证描述中的学分解析失败: " + description);
                    }
                }
            } else { // 非课程认证的逻辑（与原有逻辑保持一致）
                if (description != null) {
                    if (description.contains("完成了") && description.contains("课程")) {
                        method = "课程学习";
                        int startIndex = description.indexOf("完成了") + "完成了".length();
                        int endIndex = description.indexOf("课程");
                        if (startIndex != -1 && endIndex != -1 && startIndex < endIndex) {
                            courseName = description.substring(startIndex, endIndex).trim() + "课程";
                        } else {
                            courseName = "未知课程";
                        }
                    } else if (description.contains("证明") || description.contains("认证")) {
                        method = "学分证明";
                        courseName = null;
                    } else {
                        method = "其他认证";
                        courseName = null;
                    }
                } else {
                    method = "其他认证";
                    courseName = null;
                }
            }


            if (finalCredits == null || finalCredits < 0) {
                // 如果是课程认证，学分已经从 description 中解析。如果解析失败或仍为null，则报错。
                // 对于非课程认证，则检查传入的credits。
                return Result.failure("审核通过时，学分数量必须为非负数");
            }
            // 4.1. 创建学分记录
            CreditRecord creditRecord = new CreditRecord();
            String recordId = uuidManager.getUUID();
            if (recordId == null) {
                throw new RuntimeException("ID池已空，无法创建学分记录");
            }
            creditRecord.setId(recordId);
            creditRecord.setUserId(applicantUserId);
            creditRecord.setMethod(method);
            creditRecord.setCourseName(courseName);
            creditRecord.setCredits(finalCredits);
            creditRecord.setRecordTime(new Date());
            creditRecordsService.save(creditRecord);

            // 4.2. 更新学分汇总
            CreditSummary creditSummary = creditSummaryService.getCreditSummaryByUserId(applicantUserId);
            if (creditSummary == null) {
                creditSummary = new CreditSummary();
                creditSummary.setUserId(applicantUserId);
                creditSummary.setCurrentCredits(finalCredits);
                creditSummary.setTotalCredits(finalCredits);
                creditSummary.setLastUpdateTime(new Date());
                creditSummaryService.save(creditSummary);
            } else {
                creditSummary.setCurrentCredits(creditSummary.getCurrentCredits() + finalCredits);
                creditSummary.setTotalCredits(creditSummary.getTotalCredits() + finalCredits);
                creditSummary.setLastUpdateTime(new Date());
                creditSummaryService.updateById(creditSummary);
            }
            return Result.success("认证通过，学分已成功添加");
        } else if (auditStatus == 2) { // 审核拒绝
            return Result.success("认证已拒绝");
        } else {
            return Result.failure("无效的审核状态值");
        }
    }
}

